﻿using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace Tony.SQLServer
{
	/// <summary>
	/// SQL Server数据层基础类
	/// </summary>
	public class DataLayer : DataBase
	{
		////////////////////////////////////////////////////////////////////////////////////////////////////
		#region 属性
		public string strTableName;		// 表名字，继承类中必须初始化
		public int nIDNumber;			// 索引ID在数组中的位置，继承类中必须初始化
		public int nStatusNumber;		// 状态在数组中的位置，继承类中必须初始化
		
		protected DBOperation clsDB = new DBOperation();
		protected TableStructureComponent clsTableStructureComp = new TableStructureComponent();
		
		#endregion
		////////////////////////////////////////////////////////////////////////////////////////////////////

		#region 构造函数
		public DataLayer(string strTableName, int nIDNumber, int nStatusNumber)
		{
			this.strTableName = strTableName;
			this.nIDNumber = nIDNumber;
			this.nStatusNumber = nStatusNumber;
			InitTableStructure();
			_strSQL = "SELECT * FROM "+strTableName+" WHERE "+listStructure[this.nStatusNumber].strName+" = '"+clsConfig.nNormal.ToString()+"'";
			
			listQuery = new List<string>();
			for (int i = 0; i < listStructure.Count; i++)
			{
				if (listStructure[i].strType.ToLower() == "int")
				{
					listQuery.Add(clsConfig.nQueryConditionIntAll.ToString());

				}
				if (listStructure[i].strType.ToLower() == "char")
				{
					listQuery.Add(clsConfig.strQueryConditionStringAll);
				}
			}

		}
		
		#endregion

		#region 方法

		#region 初始化表结构链表
		/// <summary>
		/// 初始化表结构链表
		/// </summary>
		/*******************************************************************
		 * * 功    能：	初始化表结构链表
		 * * 参    数：
		 * * 返 回 值：
		 * * 作    者： Tony Mucor
		 * * 创建日期： 2013-9-10 15:25:33
		 * *******************************************************************/
		public Boolean InitTableStructure()
		{
			listStructure = clsTableStructureComp.GetTableStructure(strTableName);
			if (listStructure.Count > 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		#endregion

		#region 添加记录到数据库
		/// <summary>
		/// 添加记录到数据库
		/// </summary>
		/*******************************************************************
		 * * 功    能：
		 * * 参    数：
		 * * 返 回 值：
		 * * 作    者： Tony Mucor
		 * * 创建日期： 2013-9-10 15:12:01
		 * *******************************************************************/
		public override bool Add()
		{
			int i;
			string strTemp;
			string strSQL;
			TableStructure clsError = new TableStructure();

			if (CheckLength(ref clsError))
			{
				listStructure[nStatusNumber].strValue = clsConfig.nNormal.ToString();
				strSQL = "INSERT INTO " + strTableName + " (";
				i = 0;
				strTemp = "";
				while (i < listStructure.Count)
				{
					if (i != nIDNumber)
					{
						strTemp = strTemp + listStructure[i].strName + ", ";
					}
					i = i + 1;
				}

				strTemp = CommonFunction.ExceptString(", ", strTemp);
				strSQL = strSQL + strTemp + ") VALUES (";
				strTemp = "";
				i = 0;
				while (i < listStructure.Count)
				{
					if (i != nIDNumber)
					{
						strTemp = strTemp + "'" + listStructure[i].strValue + "', ";
					}
					i = i + 1;
				}
				strTemp = CommonFunction.ExceptString(", ", strTemp);
				strSQL = strSQL + strTemp + ")";

				if (clsDB.ExecuteSQL(strSQL) > 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				AddError(clsError.strName + "值长度错！");
				return false;
			}
		}
		#endregion

		#region 修改一条记录
		/// <summary>
		/// 修改一条记录
		/// </summary>
		/*******************************************************************
		 * * 功    能：	修改一条记录
		 * * 参    数：
		 * * 返 回 值：
		 * * 作    者： Tony Mucor
		 * * 创建日期： 2013-9-10 15:20:08
		 * *******************************************************************/
		public override bool Modify()
		{
			int i;
			string strTemp;
			string strSQL;
			TableStructure clsError = new TableStructure();

			if (CheckLength(ref clsError))
			{
				listStructure[nStatusNumber].strValue = clsConfig.nNormal.ToString();
				i = 0;
				strTemp = "";
				while (i < listStructure.Count)
				{
					if (i != nIDNumber)
					{
						strTemp = strTemp + listStructure[i].strName + " = " + "'" + listStructure[i].strValue + "', ";
					}
					i = i + 1;
				}
				strTemp = CommonFunction.ExceptString(", ", strTemp);
				strSQL = "UPDATE " + strTableName + " SET " + strTemp + " WHERE " + listStructure[nIDNumber].strName + " = '" + listStructure[nIDNumber].strValue + "' AND " + listStructure[nStatusNumber].strName + " = '" + listStructure[nStatusNumber].strValue + "'";
				if (clsDB.ExecuteSQL(strSQL) > 0)
				{
					return true;
				}
				else
				{
					return false;
				}
			}
			else
			{
				AddError(clsError.strName + "值长度错！");
				return false;
			}
		}
		#endregion

		#region 删除一条记录
		/// <summary>
		/// 删除一条记录
		/// </summary>
		/*******************************************************************
		 * * 功    能：	删除一条记录
		 * * 参    数：
		 * * 返 回 值：
		 * * 作    者： Tony Mucor
		 * * 创建日期： 2013-9-10 15:22:33
		 * *******************************************************************/
		public override bool Delete()
		{
			string strSQL;

			listStructure[nStatusNumber].strValue = clsConfig.nDelete.ToString();
			strSQL = "UPDATE " + strTableName + " SET " + listStructure[nStatusNumber].strName + " = '" + listStructure[nStatusNumber].strValue + "' WHERE " + listStructure[nIDNumber].strName + " = '" + listStructure[nIDNumber].strValue + "'";
			if (clsDB.ExecuteSQL(strSQL) > 0)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		#endregion

		/**********************************************************************************************
		 ** 函数名：	根据查询条件查询，把返回结果放到DataTable中
		 ** 功能描述：
		 ** 输入参数：
		 ** 输出参数：
		 ** 返回值：
		 ** 作者：	Tony Mucor
		 ** 日期：	2013-07-18
		 ** 备注：
		 *********************************************************************************************/
		public override DataTable QueryToDataTable(string strSQL)
		{
			return clsDB.QueryDataTable(strSQL);
		}

		/**********************************************************************************************
		 ** 函数名：	QueryOneToDataRow
		 ** 功能描述：	根据ID号查询单一记录，把结果返回到DataRow中
		 ** 输入参数：
		 ** 输出参数：
		 ** 返回值：
		 ** 作者：	Tony Mucor
		 ** 日期：	2013-07-18
		 ** 备注：
		 *********************************************************************************************/
		public override DataRow QueryOneToDataRow(int nID)
		{
			string strSQL;
			DataTable dt;

			strSQL = "SELECT * FROM " + strTableName + " WHERE " + listStructure[nIDNumber].strName + " = '" + nID.ToString() + "'";
			dt = QueryToDataTable(strSQL);

			if (dt != null)
			{
				if (dt.Rows.Count > 0)
				{
					return dt.Rows[0];
				}
				else
				{
					return null;
				}
			}
			else
			{
				return null;
			}
		}

		/**********************************************************************************************
		 ** 函数名：	QueryAll
		 ** 功能描述：	查询所有数据，把结果返回到DataTable中
		 ** 输入参数：
		 ** 输出参数：
		 ** 返回值：
		 ** 作者：	Tony Mucor
		 ** 日期：	2013-07-18
		 *********************************************************************************************/
		public override DataTable QueryAllToDataTable()
		{
			string strSQL;
			int i = 0;

			strSQL = "SELECT * FROM " + strTableName + " WHERE " + listStructure[nStatusNumber].strName + " = '" + clsConfig.nNormal.ToString() + "'";
			i = 0;
			if (listQueryOrder.Count > 0)
			{
				strSQL = strSQL + " ORDER BY";
			}
			while (i < listQueryOrder.Count)
			{
				strSQL = strSQL + " " + listStructure[listQueryOrder[i].nField].strName + " " + listQueryOrder[i].strOrder + "";
				if (i != listQueryOrder.Count - 1)
				{
					strSQL = strSQL + ",";
				}
				i = i + 1;
			}
			return QueryToDataTable(strSQL);
		}

		#region 检查添加、修改的数据是否符合数据库大小的要求
		/// <summary>
		/// 检查添加、修改的数据是否符合数据库大小的要求
		/// </summary>
		/*******************************************************************
		 * * 功    能：	检查添加、修改的数据是否符合数据库大小的要求
		 * * 参    数：	TableStructure		clsErrorEntity		有问题的表列
		 * * 返 回 值：
		 * * 作    者： Tony Mucor
		 * * 创建日期： 2013-9-10 14:56:10
		 * *******************************************************************/
		private Boolean CheckLength(ref TableStructure clsErrorEntity)
		{
			Boolean bReturn = true;
			foreach (TableStructure clsEntity in listStructure)
			{
				if (clsEntity.bCheckLength)
				{
					if (clsEntity.strValue.Length > clsEntity.nLength)
					{
						bReturn = false;
						clsErrorEntity = clsEntity;
						break;
					}
				}
			}
			return bReturn;
		}
		#endregion

		#region 查询
		/// <summary>
		/// 查询
		/// </summary>
		/*******************************************************************
		 * * 功    能：	查询
		 * * 参    数：
		 * * 返 回 值：
		 * * 作    者： Tony Mucor
		 * * 创建日期： 2013-9-25 15:43:05
		 * *******************************************************************/
		public override DataTable Query()
		{
			string strSQL;

			strSQL = "";

			for (int i = 0; i < listStructure.Count; i++)
			{
				if ((i != nIDNumber) && (i != nStatusNumber))
				{
					if (listStructure[i].strType.ToLower() == "int")
					{
						if (listQuery[i] != clsConfig.nQueryConditionIntAll.ToString())
						{
							strSQL = strSQL + " AND "+listStructure[i].strName+" = '"+listQuery[i]+"'";
						}
					}
					if (listStructure[i].strType.ToLower() == "char")
					{
						if (listQuery[i] != clsConfig.strQueryConditionStringAll)
						{
							strSQL = strSQL + " AND "+listStructure[i].strName+" LIKE '%"+listQuery[i]+"%'";
						}
					}
				}
			}

			if (listQueryOrder.Count > 0)
			{
				strSQL = strSQL + " ORDER BY";
			}
			for (int i = 0; i < listQueryOrder.Count; i++)
			{
				strSQL = strSQL + " "+listStructure[listQueryOrder[i].nField].strName+" "+listQueryOrder[i].strOrder+"";
				if (i != listQueryOrder.Count - 1)
				{
					strSQL = strSQL + ",";
				}
			}

			strSQL = _strSQL + strSQL;

			return QueryToDataTable(strSQL);
		}
		#endregion
		#endregion

		////////////////////////////////////////////////////////////////////////////////////////////////////
		//
		/// <summary>
		/// 根据查询条件实体查询
		/// </summary>
		/// <param name="clsQuery"></param>
		/// <returns></returns>
		public override DataTable Query(QueryEntityBase clsQuery, List<Structs.QueryData> listQueryData)
		{
			string strSQL = "";
			string strField = "";

			strSQL = _strSQL;
			DataLayer clsDataLayer;

			for (int i = 0; i < listQueryData.Count; i++)
			{

				if (listQueryData[i].clsDataBase == null)
				{
					clsDataLayer = this;
				}
				else
				{
					clsDataLayer = (DataLayer) listQueryData[i].clsDataBase;
				}

				if (listQueryData[i].bDateTime)
				{
					strField = "CAST (" + clsDataLayer.listStructure[listQueryData[i].nDatabaseOrder].strName + " AS DATETIME)";
				}
				else
				{
					strField = clsDataLayer.listStructure[listQueryData[i].nDatabaseOrder].strName;
				}

				if (listQueryData[i].strType == "int")
				{
					if (clsQuery.GetType().GetField(listQueryData[i].strVarName).GetValue(clsQuery).ToString() != clsConfig.nQueryConditionIntAll.ToString())
					{
						strSQL = strSQL + " AND " + strField + " " + listQueryData[i].strQuery + " '" + clsQuery.GetType().GetField(listQueryData[i].strVarName).GetValue(clsQuery).ToString() + "'";
					}
				}

				if (listQueryData[i].strType == "string")
				{
					if (clsQuery.GetType().GetField(listQueryData[i].strVarName).GetValue(clsQuery).ToString() != clsConfig.strQueryConditionStringAll)
					{
						if (listQueryData[i].strQuery.ToUpper() == "IN")
						{
							strSQL = strSQL + " AND " + strField + " " + listQueryData[i].strQuery + " (" + clsQuery.GetType().GetField(listQueryData[i].strVarName).GetValue(clsQuery).ToString() + ")";
						}
						else
						{
							if (listQueryData[i].strQuery.ToUpper() == "LIKE")
							{
								strSQL = strSQL + " AND " + strField + " " + listQueryData[i].strQuery + " '%" + clsQuery.GetType().GetField(listQueryData[i].strVarName).GetValue(clsQuery).ToString() + "%'";
							}
							else
							{
								strSQL = strSQL + " AND " + strField + " " + listQueryData[i].strQuery + " '" + clsQuery.GetType().GetField(listQueryData[i].strVarName).GetValue(clsQuery).ToString() + "'";
							}
						}
					}
				}
			}

			strSQL = strSQL + _strOrder;

			return clsDB.QueryDataTable(strSQL);
		}
		////////////////////////////////////////////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////////////////////////////////////////////
		//
		/// <summary>
		/// 查询最新插入记录的ID号
		/// </summary>
		/// <returns></returns>
		public override int QueryNewestInsertID()
		{
			string strSQL;
			DataTable dt;

			strSQL = "SELECT TOP 1 * FROM " + strTableName + " WHERE " + listStructure[nStatusNumber].strName + " = " + clsConfig.nNormal.ToString() + " ORDER BY " + listStructure[nIDNumber].strName + " DESC";
			dt = clsDB.QueryDataTable(strSQL);
			if (dt != null)
			{
				return Convert.ToInt32(dt.Rows[0][nIDNumber]);
			}
			else
			{
				return 1;
			}
		}
		////////////////////////////////////////////////////////////////////////////////////////////////////
	}
}